/*
 * 文 件 名:  DateUtil.java
 * 版    权:  easylinkin Technologies Co., Ltd. Copyright 2013-2023,  All rights reserved
 * 描    述:  <描述>
 * 修 改 人:  user
 * 修改时间:  2013-3-30
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.easylinkin.linkappapi.common.utils;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.easylinkin.linkappapi.common.constant.CommonConstant;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.device.constant.DeviceConstant.GrainSize;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

/**
 * <一句话功能简述> <功能详细描述>
 *
 * @author Administrator
 */
public class DateUtil {

    public static String yyyyMM = "yyyyMM";
    
    public static String yyyy_MM = "yyyy-MM";

    private DateUtil() {

    }

    private static final Logger log = LoggerFactory.getLogger(DateUtil.class);

    public static final String DATE_TIME_FORMAT_DEFAULT = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_TIME_NUMBER_STRING = "yyyyMMddHHmmssSSS";

    public static final String YYYYMMDDHHMM_STRING = "yyyyMMddHHmm";
    
    public static final String YYYYMMDDHH_STRING = "yyyyMMddHH";

    public static final String DATE_TIME_FORMAT_SLASH = "yyyy/MM/dd HH:mm:ss";

    public static final String DATE_TIME_FORMAT_MINUTE = "yyyy-MM-dd HH:mm";

    public static final String DATE_TIME_FORMAT_HOUR = "yyyy-MM-dd HH";

    public static final String DATE_TIME_FORMAT_DAY = "yyyy-MM-dd";

    public static final String DATE_TIME_FORMAT_DAY_2 = "yyyy/MM/dd";

    public static final String DATE_TIME_FORMAT_MONTH = "yyyy-MM";

    public static final String DATE_TIME_FORMAT_YEAR = "yyyy";

    public static final String DATE_TIME_FORMAT_MONTH_DAY = "MM-dd";

    public static final String DATE_TIME_FORMAT_HMS = "HH:mm:ss";

    public static final String DATE_TIME_FORMAT_HM = "HH:mm";

    public static final String DATE_START_HMS = " 00:00:00";
    public static final String DATE_END_HMS = " 23:59:59";

    protected static final String[] WEEKDAYS = {"周日", "周一", "周二", "周三", "周四",
        "周五", "周六"};

    /**
     * 填充日期 的最小和最大的时分秒部分
     * @param date
     * @return
     */
    public static String[] fillDateHHMMSS(String date){
        String[] dates = new String[2];
        dates[0] = fillDateStartHHMMSS(date);
        dates[1] = fillDateEndHHMMSS(date);
        return dates;
    }

    public static String fillDateStartHHMMSS(String date){
        String result = StrUtil.concat(true, date, DATE_START_HMS);
        return result;
    }

    public static String fillDateEndHHMMSS(String date){
        String result = StrUtil.concat(true, date, DATE_END_HMS);
        return result;
    }

    /**
     * <根据格式化返回日期> <根据格式化返回日期>
     *
     * @param str str
     * @param format format
     * @return Date
     * @see [类、类#方法、类#成员]
     */
    public static Date setDate(String str, String format) {
        if (str == null || str.trim().length() == 0) {
            return null;
        }

        if (DATE_TIME_FORMAT_DAY.equals(format) && str.trim().length() == CommonConstant.TEN) {
            Calendar cal = Calendar.getInstance();
            cal.set(Integer.parseInt(str.substring(0, 4)),
                Integer.parseInt(str.substring(5, 7)) - 1,
                Integer.parseInt(str.substring(8, 10)));
            return cal.getTime();
        } else if (DATE_TIME_FORMAT_DEFAULT.equals(format)
            && str.trim().length() == 19) {
            Calendar cal = Calendar.getInstance();
            cal.set(Integer.parseInt(str.substring(0, 4)),
                Integer.parseInt(str.substring(5, 7)) - 1,
                Integer.parseInt(str.substring(8, 10)),
                Integer.parseInt(str.substring(11, 13)),
                Integer.parseInt(str.substring(14, 16)),
                Integer.parseInt(str.substring(17, 19)));
            return cal.getTime();
        } else if (DATE_TIME_FORMAT_HMS.equals(format)
            && str.trim().length() == 8) {
            Calendar cal = Calendar.getInstance();
            cal.set(9999,
                11,
                31,
                Integer.parseInt(str.substring(0, 2)),
                Integer.parseInt(str.substring(3, 5)),
                Integer.parseInt(str.substring(6, 8)));
            return cal.getTime();
        } else {
            return null;
        }
    }

    /**
     * 年
     */
    public static final String YEAR = "year";

    /**
     * 月
     */
    public static final String MONTH = "month";

    /**
     * 日
     */
    public static final String DAY = "day";

    /**
     * 小时
     */
    public static final String HOUR = "hour";

    /**
     * 分钟
     */
    public static final String MINUTE = "minute";

    /**
     * 秒
     */
    public static final String SECOND = "second";

    /**
     * <返回日期的年、月、日、小时> <返回日期的年、月、日、小时>
     *
     * @param date date
     * @param type type
     * @return int
     * @see [类、类#方法、类#成员]
     */
    public static int get(Date date, String type) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (type.equalsIgnoreCase(YEAR)) {
            return cal.get(Calendar.YEAR);
        } else if (type.equalsIgnoreCase(MONTH)) {
            return cal.get(Calendar.MONTH) + 1;
        } else if (type.equalsIgnoreCase(DAY)) {
            return cal.get(Calendar.DAY_OF_MONTH);
        } else if (type.equalsIgnoreCase(HOUR)) {
            return cal.get(Calendar.HOUR_OF_DAY);
        } else if (type.equalsIgnoreCase(MINUTE)) {
            return cal.get(Calendar.MINUTE);
        } else if (type.equalsIgnoreCase(SECOND)) {
            return cal.get(Calendar.SECOND);
        }
        return 0;
    }

    /**
     * 返回时间字符串：yyyy-MM-dd HH:mm:ss
     *
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getDate() {
        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_DEFAULT);
        return df.format(now());
    }

    /**
     * <返回当前系统时间> <返回当前系统时间>
     *
     * @return String
     * @see [类、类#方法、类#成员]
     */
    public static String sysdate(String format) {
        return new SimpleDateFormat(format).format(sysDateTime());
    }

    public static Date now() {
        return new Date();
    }

    /**
     * <返回当前系统时间> <返回当前系统时间>
     *
     * @return Timestamp
     * @see [类、类#方法、类#成员]
     */
    public static Timestamp sysDateTime() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * <字符串类型转换成日期类型> <字符串类型转换成日期类型>
     *
     * @param format format
     * @return Date
     * @see [类、类#方法、类#成员]
     */
    public static Date parse(String date, String format) {
        try {
            SimpleDateFormat df = new SimpleDateFormat(format);
            return df.parse(date);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * <判断是否是整点时间> <判断是否是整点时间>
     *
     * @param s s
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean isExactTime(String s) {
        boolean isExact = false;

        Date date = parse(s, DATE_TIME_FORMAT_DEFAULT);

        if (date != null) {
            GregorianCalendar gc = new GregorianCalendar();
            gc.setTime(date);
            if (gc.get(Calendar.MINUTE) == 0 && gc.get(Calendar.SECOND) == 0) {
                isExact = true;
            }
        }

        return isExact;
    }

    /**
     * <获取当前小时的上个小时> <获取当前小时的上个小时>
     *
     * @return String
     * @see [类、类#方法、类#成员]
     */
    public static String beforeHour() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.HOUR_OF_DAY, -1);
        SimpleDateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_HOUR);
        return df.format(cal.getTime());
    }

    /**
     * <按格式截取日期> <按格式截取日期>
     *
     * @param s s
     * @return String
     * @see [类、类#方法、类#成员]
     */
    public static String concat(String s, String format) {
        String result = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date = sdf.parse(s);

            result = sdf.format(date);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }

        return result;

    }

    /**
     * 根据年和周计算日期范围
     *
     * @param year 年
     * @param week 周
     * @return 返回日期范围 [0]开始时间，[1]结束时间
     * @see [类、类#方法、类#成员]
     */
    public static Date[] calWeekDate(int year, int week) throws ParseException {
        Date[] dates = new Date[2];
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT_DAY);
        String datetime = year + "-01-01";
        Date date = sdf.parse(datetime);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        if (c.get(Calendar.DAY_OF_WEEK) == CommonConstant.TWO) {
            c.add(Calendar.DAY_OF_YEAR, (week - 1) * 28);
        } else {
            int dayOfweek = c.get(Calendar.DAY_OF_WEEK);
            dayOfweek = dayOfweek == 1 ? -6 : 2 - dayOfweek;
            c.add(Calendar.DAY_OF_YEAR, dayOfweek);
            c.add(Calendar.DAY_OF_YEAR, (week - 1) * 7);
        }

        dates[0] = c.getTime();
        Calendar c1 = (Calendar) c.clone();
        c1.add(Calendar.DAY_OF_YEAR, 6);
        dates[1] = c1.getTime();

        return dates;
    }

    /**
     * 返回当前年 格式yyyy
     */
    public static String getCurrentYear() {
        Calendar cal1 = Calendar.getInstance();
        Timestamp currentTime = sysDateTime();

        cal1.setTime(new Date(currentTime.getTime()));
        Integer year = Integer.valueOf(cal1.get(Calendar.YEAR));
        return year.toString();
    }

    /**
     * 返回当前月
     */
    public static String getCurrentMM() {
        Calendar cal = Calendar.getInstance();
        Timestamp currentTime = sysDateTime();
        cal.setTime(new Date(currentTime.getTime()));
        Integer month = Integer.valueOf(cal.get(Calendar.MONTH) + 1);
        return month.toString();
    }

    public static void main(String[] args) throws Exception{
//        System.out.println("args = " + getCurrentMM());
        List<Date> dateList = getAllMonthEndDay("2022-07-01 00:00:00","2022-07-30 23:59:59");
        System.out.println("args = " + dateList);
    }


    /**
     * 根据日期时间 只取年月日
     *
     * @param date
     * @return
     */
    public static String getYYYYMMDDDate(Date date) {
        if (date == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_DAY);

        return df.format(date);
    }


    /**
     * 根据日期时间 只取时分数据
     *
     * @param date
     * @return
     */
    public static String getHHMMDate(Date date) {
        if (date == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_HM);
        return df.format(date);
    }

    /**
     * @return //yyyy-MM-dd HH:mm:ss格式的日期字符串
     */
    public static String getYYYYMMDDHHMMSSDate(Date date) {
        if (null == date) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_DEFAULT);
        return df.format(date);
    }

    public static String getyyyyMMddHHmmssSSSNumberString(Date date) {
        if (null == date) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(DATE_TIME_NUMBER_STRING);
        return df.format(date);
    }


    public static String getyyyyMMddHHmmNumberString(Date date) {
        if (null == date) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(YYYYMMDDHHMM_STRING);
        return df.format(date);
    }

    /**
     * 返回格式 2021011813
     * @param date
     * @return
     */
    public static String getYYYYMMDDHHNumberString(Date date) {
        if (null == date) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(YYYYMMDDHH_STRING);
        return df.format(date);
    }

    /**
     * YYYYMMDD格式字符串转换为日期
     *
     * @param dateString YYYYMMDD格式字符串
     * @return 日期
     */
    public static Date getDateFromYYYYMMDD(String dateString) {

        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_DAY);
        df.setLenient(false);

        try {
            return df.parse(dateString);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("根据字符串：" + dateString + "解析时间失败，请检查字符串格式");
        }
    }

    public static Date getDateFromYYYYMMDDHHmmss(String dateString) {

        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_DEFAULT);
        df.setLenient(false);
        try {
            return df.parse(dateString);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("根据字符串：" + dateString + "解析时间失败，请检查字符串格式");
        }
    }

    public static Date getDateFromFormatStr(String dateString,String formatedStr) {

        DateFormat df = new SimpleDateFormat(formatedStr);
        df.setLenient(false);
        try {
            return df.parse(dateString);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("根据字符串：" + dateString + "解析时间失败，请检查字符串格式");
        }
    }

    /**
     * 返回格式化时间的字符串格式
     * @param date
     * @param formatStr
     * @return
     */
    public static String getDateFromFormatStr(Date date, String formatStr) {
        if (null == date) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(formatStr);
        return df.format(date);
    }

    /**
     * 获取月末日期
     *
     * @param monthBegin 年月字符串 如2013-01-01
     * @return 返回指定月的月末日期字符串 如2013-01-31
     */
    public static String getMonthDate(String monthBegin) {
        // 获取月首到月尾
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(DateUtil.getDateFromYYYYMMDD(monthBegin));
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);

        return DateUtil.getYYYYMMDDDate(calendar.getTime());
    }

    /**
     * 获取当前日期字符串是改年的多少天
     *
     * @param dateStr yyyy-MM-dd
     * @return int该年第n天
     * @see [类、类#方法、类#成员]
     */
    public static int getDayOfYear(String dateStr) {
        int result = 0;
        result = getDayOfYear(DateUtil.getDateFromYYYYMMDD(dateStr));

        return result;
    }

    /**
     * 获取当前日期是该年的多少天
     *
     * @see [类、类#方法、类#成员]
     */
    public static int getDayOfYear(Date date) {

        // 获取月首到月尾
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);

        return calendar.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 获取当前日期字符串是哪个月
     *
     * @see [类、类#方法、类#成员]
     */
    public static int getMonthOfYear(String dateStr) {
        int result = 0;
        result = getMonthOfYear(DateUtil.getDateFromYYYYMMDD(dateStr));
        return result;
    }

    /**
     * 获取当前日期是哪个月
     *
     * @see [类、类#方法、类#成员]
     */
    public static int getMonthOfYear(Date date) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);

        // 月份从0开始,所以需要加1
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前日期字符串的年份
     *
     * @see [类、类#方法、类#成员]
     */
    public static int getYear(String dateStr) {
        int result = 0;
        result = getYear(DateUtil.getDateFromYYYYMMDD(dateStr));
        return result;
    }

    /**
     * 获取当前日期的年份
     *
     * @see [类、类#方法、类#成员]
     */
    public static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);

        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取当前日期字符串是星期几
     *
     * @see [类、类#方法、类#成员]
     */
    public static String getWeekOfDate(String dateStr) {
        String result = "0";
        result = getWeekOfDate(DateUtil.getDateFromYYYYMMDD(dateStr));
        return result;
    }

    /**
     * 获取当前日期是星期几
     *
     * @see [类、类#方法、类#成员]
     */
    public static String getWeekOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return WEEKDAYS[w];
    }

    /**
     * 通过年和该年第n天，获取日期字符串
     *
     * @param year 指定年
     * @param day 指定第n天
     * @return 日期字符串，如2013-01-01
     */
    public static String getDateStrByDay(int year, int day) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.DAY_OF_YEAR, day);

        return getYYYYMMDDDate(calendar.getTime());
    }

    /**
     * 获取年的周数
     *
     * @param year 年
     * @return 返回周数
     * @see [类、类#方法、类#成员]
     */
    public static int getWeekNumByYear(int year) {
        // 每年至少有52个周 ，最多有53个周
        int result = 52;
        String date = getYearWeekFirstDay(year, 52 + 1);

        // 判断年度是否相符，如果相符说明有53个周。
        if (date.substring(0, CommonConstant.FOUR).equals(year + "")) {
            result = 53;
        }
        return result;
    }

    /**
     * 设置年日期
     *
     * @param yearNum 年
     * @param weekNum 周
     * @return 返回日期
     * @see [类、类#方法、类#成员]
     */
    public static String getYearWeekFirstDay(int yearNum, int weekNum) {
        Calendar cal = Calendar.getInstance();
        // 设置每周的第一天为星期日
        cal.setFirstDayOfWeek(Calendar.SUNDAY);
        // 每周从周日开始
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);

        // 上面两句代码配合，才能实现，每年度的第一个周，是包含第一个星期日的那个周。
        // 设置每周最少为7天
        cal.setMinimalDaysInFirstWeek(7);

        cal.set(Calendar.YEAR, yearNum);
        cal.set(Calendar.WEEK_OF_YEAR, weekNum);

        SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT_DAY);
        return format.format(cal.getTime());
    }

    /**
     * 判断是否闰年
     */
    public static boolean isLeapYear(int year) {
        return year % 100 == 0 ? year % 400 == 0 : year % 4 == 0;
    }

    /**
     * 获得某个月有几天
     */
    public static int getMonthDay(int year, int month) {
        switch (month) {
            case 1:
                return 31;
            case 2:
                return isLeapYear(year) ? 29 : 28;
            case 3:
                return 31;
            case 4:
                return 30;
            case 5:
                return 31;
            case 6:
                return 30;
            case 7:
                return 31;
            case 8:
                return 31;
            case 9:
                return 30;
            case 10:
                return 31;
            case 11:
                return 30;
            case 12:
                return 31;
            default:
                return -1;
        }
    }

    /**
     * 按照给定的格式，格式化时间
     *
     * @param date java.util.Date
     * @author OuYangGuoDong 2014-9-4
     * @see [类、类#方法、类#成员]
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 获取当前时间往后一个小时之内的HH:mm时间段(10:10 10:15 10:20...) <一句话功能简述> <功能详细描述>
     *
     * @see [类、类#方法、类#成员]
     */
    public static List<String> getAfterOneHour() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT_HM);
        List<String> sList = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        sList.add(dateFormat.format(cal.getTime()));
        for (int i = 0; i < CommonConstant.TWELVE; i++) {
            cal.add(Calendar.MINUTE, 5);
            sList.add(dateFormat.format(cal.getTime()));
        }

        return sList;
    }

    /**
     * 获取当前时间
     *
     * @param formatStr 日期格式
     * @see [类、类#方法、类#成员]
     */
    public static String getCurrentDateStr(String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        return sdf.format(new Date());
    }

    /**
     * Function Name               addYear
     *
     * @return //返回增加后的日期对象
     * @description //在“今天”的基础上，取得前N年后的日期
     */
    public static Date addYear(Date date, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, amount);
        return calendar.getTime();
    }

    /**
     * 日期增加n天
     *
     * @param date 日期
     * @param amount 增加的天数
     * @return 增加后的日期
     */
    public static Date addMonth(Date date, int amount) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, amount);
        return calendar.getTime();
    }

    /**
     * 日期增加n天
     *
     * @param date 日期
     * @param amount 增加的天数
     * @return 增加后的日期
     */
    public static Date addDay(Date date, int amount) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, amount);
        return calendar.getTime();
    }

    /**
     * 日期增加n小时
     *
     * @see [类、类#方法、类#成员]
     */
    public static Date addHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        return calendar.getTime();
    }

    /**
     * 日期增加n分钟
     *
     * @param date 日期
     * @param minute 增加的分钟
     * @return 增加后的日间字符串
     */
    public static String addMinute(Date date, int minute) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT_HM);
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 日期增加n分钟
     *
     * @param date 日期
     * @param minute 增加的分钟
     * @return 增加后的日间字符串
     */
    public static Date addMinuteReturnDate(Date date, int minute) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 日期增加n秒
     *
     * @see [类、类#方法、类#成员]
     */
    public static Date addSecond(Date date, int second) {
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * 返回两个时间相差的天数 <功能详细描述>
     *
     * @see [类、类#方法、类#成员]
     */
    public static int daysBetween(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();
        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();
        long betweenDays = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(betweenDays));
    }

    /**
     * 返回两个时间相差的时分秒 <功能详细描述>
     *
     * @see [类、类#方法、类#成员]
     */
    public static String hoursBetween(Date date1, Date date2) {
        long hour = 0;
        long min = 0;
        long sec = 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();
        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();
        long betweenSecond = (time2 - time1) * 1000;
        hour = betweenSecond / 3600;
        min = (betweenSecond - hour * 3600) / 60;
        sec = betweenSecond - hour * 3600 - min * 3600 * 60;

        return +hour + "小时" + min + "分" + sec + "秒";
    }

    /**
     * 取得当天的最小时间，如2011-11-11 00:00:00
     *
     * @param d 当前时间
     */
    public static Date getCurrentDayMixDate(Date d) {
        Date currentDate = null;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);

        String dateStr = format(cal.getTime(), DATE_TIME_FORMAT_DAY);
        dateStr += " 00:00:00";
        currentDate = parse(dateStr, DATE_TIME_FORMAT_DEFAULT);
        return currentDate;
    }

    /**
     * 取得当天的最小时间，如2011-11-11 00:00:00
     *
     * @param d 当前时间
     */
    public static Date getCurrentDayMaxDate(Date d) {
        Date currentDate = null;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);

        String dateStr = format(cal.getTime(), DATE_TIME_FORMAT_DAY);
        dateStr += " 23:59:59";
        currentDate = parse(dateStr, DATE_TIME_FORMAT_DEFAULT);
        return currentDate;
    }

    public static Date getCurrentDayMixDate() {
        Date currentDate = null;
        Calendar cal = Calendar.getInstance();

        String dateStr = format(cal.getTime(), DATE_TIME_FORMAT_DAY);
        dateStr += " 00:00:00";
        currentDate = parse(dateStr, DATE_TIME_FORMAT_DEFAULT);
        return currentDate;
    }

    public static Date getCurrentDayMaxDate() {
        Date currentDate = null;
        Calendar cal = Calendar.getInstance();

        String dateStr = format(cal.getTime(), DATE_TIME_FORMAT_DAY);
        dateStr += " 23:59:59";
        currentDate = parse(dateStr, DATE_TIME_FORMAT_DEFAULT);
        return currentDate;
    }

    public static String unitFormat(long i) {
        String retStr = null;
        if (i >= 0 && i < CommonConstant.TEN) {
            retStr = "0" + i;
        } else {
            retStr = "" + i;
        }
        return retStr;
    }

    /**
     * 将秒数 转化为hh:mm:ss
     *
     * @see [类、类#方法、类#成员]
     */
    public static String formatSeconds(long second) {
        long hour = 3600L;
        long minute = 60L;
        long h = 0L;
        long d = 0L;
        long s = 0L;
        long temp = second % hour;

        if (second > hour) {
            h = second / hour;
            if (temp != 0) {
                if (temp > minute) {
                    d = temp / minute;
                    if (temp % minute != 0) {
                        s = temp % minute;
                    }
                } else {
                    s = temp;
                }
            }
        } else {
            d = second / minute;
            if (second % minute != 0) {
                s = second % minute;
            }
        }

        return unitFormat(h) + ":" + unitFormat(d) + ":" + unitFormat(s);
    }

    /**
     * 获取指定日期近三个月最早的时间点 例如:指定时间是2016-09-05 11:07:18,返回:2016-07-01 00:00:00
     *
     * @author OuYangGuoDong
     * @see [类、类#方法、类#成员]
     */
    public static Date getBeforeThreeMonthTimePoint(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.add(Calendar.MONTH, -2);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取指定年月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }

    /**
     * 判断是否为同一天
     *
     * @see [类、类#方法、类#成员]
     */
    public static boolean isSameDate(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2
            .get(Calendar.YEAR);
        boolean isSameMonth = isSameYear
            && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        return isSameMonth
            && cal1.get(Calendar.DAY_OF_MONTH) == cal2
            .get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 比较最大日期与当前日期 20190828
     *
     * @param maxDate 日期 格式：2019/07/07
     * @return 大于0：最大日期大于当前日期；小于0：最大日期小于当前日期；等于0：最大日期等于当前日期
     */
    public static int compareTo(String maxDate) {
        Date date = new Date();
        DateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT_DAY_2);
        String nowDate = format.format(date);
        return maxDate.compareTo(nowDate);
    }

    public static Date localDateTimeToDate(LocalDateTime localDateTime){
        Date date = Date.from( localDateTime.atZone( ZoneId.systemDefault()).toInstant());
        return date;
    }

    /**
     * 覆盖结束过滤时间 2020-04-21 覆盖为 2020-04-21 23:59:59
     * @param queryTimeEnd
     * @return
     */
    public static String overQueryTimeEnd(String queryTimeEnd) {
        if(StringUtils.isBlank(queryTimeEnd)){
            return null;
        }
        queryTimeEnd = queryTimeEnd.trim();
        if (queryTimeEnd.matches("^\\d+[/-]\\d+[/-]\\d+$")) {
            queryTimeEnd = queryTimeEnd + DATE_END_HMS;
        }

        return queryTimeEnd;
    }


    /**
     * 处判断当前时间和传入的时间相差值是否超过?小时
     * return true 在范围内
     *        false  非范围
     * ***/
    public static boolean queryDateIsBeyondVal(Date date,int val) {
        //现在时间 2020-28-12
        Calendar nowDate = Calendar.getInstance();
        nowDate.setTime(new Date());
        nowDate.set(Calendar.SECOND, 0);
        nowDate.set(Calendar.MILLISECOND, 0);

        Calendar  afterInstance= Calendar.getInstance();
        afterInstance.setTime(date);
        afterInstance.add(Calendar.HOUR, +val);


        Calendar  beforeInstance = Calendar.getInstance();
        beforeInstance.setTime(date);

        beforeInstance.add(Calendar.HOUR, -val);
        return nowDate.after(beforeInstance) && nowDate.before(afterInstance);
    }


    /**
     * @param pattern 模板
     * @param addMonth 要增加的月份 1-下个月，-1 上个月，0-当前月
     * @return yyyyMM 或yyyy-MM 字符串
     */
    public static String getyyyyMM(String pattern, int addMonth) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, addMonth);
        return simpleDateFormat.format(calendar.getTime());
    }

    /**
     * 验证指定日期是否是周末日期
     * @param date  指定日期
     * @return true：是周末；false:工作日
     */
    public static boolean isWeekend(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week=cal.get(Calendar.DAY_OF_WEEK)-1;
        //0代表周日，6代表周六
        return week == 6 || week == 0;
    }

    /**
     * 获取传入时间的周一
     *
     * @param date 当前时间
     * @return 返回传入时间当周星期一
     */
    public static Date getNowWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.add(Calendar.DAY_OF_MONTH, -1); //解决周日会出现 并到下一周的情况
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        return cal.getTime();
    }

    /**
     * 返回当月第一天
     * @param date 当前时间
     * @return 返回当月第一天
     */
    public static Date getNowMonthFirstDay(Date date) {
        return setDays(date,1);
    }

    /**
     * 设置天数
     *
     * @param date
     *            当前时间
     * @param amount
     *            设置天数 传入Int类型
     * @return 设置后时间
     */
    public static Date setDays(Date date, int amount) {
        return DateUtils.setDays(date, amount);
    }


    public static List<Date> checkDateIsLegal(Byte grain_size, String startDay, String endDay){
        List<Date> times = null;
        try {
            if(GrainSize.DAY.equals(grain_size)){
                times = findDates(startDay, endDay);
                if(CollectionUtil.isEmpty(times)){
                    // 日期选择区间 无数据可展示
                    return null;
                }
                return times;
            }
            if(GrainSize.WEEK.equals(grain_size)){
                times = getAllWeekend(startDay,endDay);
                if(CollectionUtil.isEmpty(times)){
                    // 日期选择区间 无数据可展示
                    return null;
                }
                return times;
            }
            if(GrainSize.MONTH.equals(grain_size)){
                times = getAllMonthEndDay(startDay,endDay);
                if(CollectionUtil.isEmpty(times)){
                    // 日期选择区间 无数据可展示
                    return null;
                }
                return times;
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return times;
    }

    /**
     * 获取两个日期之间的所有的日期
     * @param dBegin
     * @param dEnd
     * @return
     * @throws ParseException
     */
    public static List<Date> findDates(String dBegin, String dEnd) throws ParseException {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(dBegin));
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(dEnd));
        List<Date> list = new ArrayList<>();
        list.add(format.parse(dBegin));
        while (format.parse(dEnd).after(calBegin.getTime())) {
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            list.add(calBegin.getTime());
        }

        return list;
    }

    /**
     * 获取两个日期之间的所有的周末
     * @param startDate
     * @param endDate
     * @return
     * @throws Exception
     */
    public static List<Date> getAllWeekend(String startDate, String endDate) throws Exception {

        // 获取两个日期之间的所有日期
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(startDate));
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(endDate));
        List<Date> list = new ArrayList<>();
        while (format.parse(endDate).after(calBegin.getTime())) {
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            Date date = calBegin.getTime();
            Calendar c1 = Calendar.getInstance();
            c1.setTime(date);
            int num = calBegin.get(Calendar.DAY_OF_WEEK);
            if(Calendar.SUNDAY == num){
                list.add(date);
            }
        }

        if(CollectionUtil.isNotEmpty(list)){
            Calendar lastWeekend = Calendar.getInstance();
            lastWeekend.setTime(list.get(list.size()-1));
            if(format.parse(endDate).after(lastWeekend.getTime())){
                lastWeekend.add(Calendar.DAY_OF_MONTH, 7);
                Date date = lastWeekend.getTime();
                Calendar c1 = Calendar.getInstance();
                c1.setTime(date);
                list.add(date);
            }
        }
        return list;
    }

    /**
     * 获取两个日期之间的所有的月末
     * @param startDate
     * @param endDate
     * @return
     * @throws Exception
     */
    public static List<Date> getAllMonthEndDay(String startDate, String endDate) throws Exception {

        // 获取两个日期之间的所有日期
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(startDate));
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(endDate));
        List<Date> list = new ArrayList<>();
        while (format.parse(endDate).after(calBegin.getTime())) {
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            Date date = calBegin.getTime();
            Calendar c1 = Calendar.getInstance();
            c1.setTime(date);
            c1.add(Calendar.DAY_OF_MONTH, 1);

            int month1 = calBegin.get(Calendar.MONTH);
            int month2 = c1.get(Calendar.MONTH);

            if(month1 != month2){
                list.add(date);
            }


        }
        if(CollectionUtil.isNotEmpty(list)){
            Calendar lastMonthEnd = Calendar.getInstance();
            lastMonthEnd.setTime(list.get(list.size()-1));
            if(format.parse(endDate).after(lastMonthEnd.getTime())){
                lastMonthEnd.add(Calendar.MONTH, 1);
                Date date = lastMonthEnd.getTime();
                Calendar c1 = Calendar.getInstance();
                c1.setTime(date);
                list.add(date);
            }
        }

        return list;
    }

    /**
     * 获取月初
     * @param day
     * @return firstday
     */
    public static Date findFirstDayOfMonth(Date day) {
        //获取月末
        // 获取当月第一天和最后一天
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date firstday;
        // 获取前月的第一天
        Calendar cale = Calendar.getInstance();
        cale.setTime(day);
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        firstday = cale.getTime();
        return firstday;
    }

    /**
     * 根据日期字符串判断当年第几周
     *
     * @param date
     * @return 202101
     * @throws Exception
     */
    public static String getWeekOfYear(Date date) throws Exception {
        StringBuilder sb = new StringBuilder();
        date = findMondayBySunDay(date);
        // 将字符串格式化
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周的第一天
        calendar.setMinimalDaysInFirstWeek(4);
        calendar.setTime(date);
        // 第几周
        int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
        sb.append(calendar.get(Calendar.YEAR))
            .append(weekOfYear > 9 ? "" + weekOfYear : "0" + weekOfYear);
        return sb.toString();
    }

    /**
     * 通过周日查找周一
     * @param sunDay
     * @return
     * @throws ParseException
     */
    public static Date findMondayBySunDay(Date sunDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(sunDay);
        calendar.add(Calendar.DAY_OF_MONTH, -6);
        return calendar.getTime();
    }

    /**
     * 根据某年某月获取时间区间
     * @param monthOfYear yyyyMM
     * @return
     */
    public static String getTimeIntervalByMonth(String monthOfYear){
        StringBuilder sb = new StringBuilder();
        int year = Integer.valueOf(monthOfYear.substring(0,4));
        int month = Integer.valueOf(monthOfYear.substring(4,6));
        String firstDay = getFisrtDayOfMonth(year,month);
        String endDay = getLastDayOfMonth(year,month);
        sb.append(firstDay).append("~").append(endDay);
        return sb.toString();
    }

    public static String getFisrtDayOfMonth(int year,int month){
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR,year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最小天数
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH, firstDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String firstDayOfMonth = sdf.format(cal.getTime());

        return firstDayOfMonth;
    }

    public static String getTimeIntervalByWeek(String weekOfYear) {
        StringBuilder sb = new StringBuilder();
        int year = Integer.valueOf(weekOfYear.substring(0,4));
        int week = Integer.valueOf(weekOfYear.substring(4,6)) + 1;
        Calendar calendar = Calendar.getInstance();
//    calendar.set(year, 0, 1);
//    int dayOfWeek = 7- calendar.get(Calendar.DAY_OF_WEEK) + 1;//算出第一周还剩几天 +1是因为1号是1天
//    week = week -2;//周数减去第一周再减去要得到的周
//    calendar.add(Calendar.DAY_OF_YEAR, week*7+dayOfWeek);
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.WEEK_OF_YEAR,week);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        calendar.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);
        String firstDay = sdf.format(calendar.getTime());
//    System.out.println("开始日期："+new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
//    calendar.add(Calendar.DAY_OF_YEAR, 6);
        calendar.set(Calendar.WEEK_OF_YEAR,week+1);
        calendar.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
//    System.out.println("结束日期："+new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
        String endDay = sdf.format(calendar.getTime());

        sb.append(firstDay).append("~").append(endDay);
        return sb.toString();
    }


    public static void checkDate(Byte grainSize,Date startTime,Date endTime){
        int daysBetween = daysBetween(startTime,endTime);
        if(GrainSize.DAY.equals(grainSize)&&daysBetween<1){
            Assert.isTrue(false, "选择粒度日时，时间范围应大于2天");
        }else if(GrainSize.WEEK.equals(grainSize)&&daysBetween<7){
            Assert.isTrue(false, "选择粒度周时，时间范围应大于1周");
        }else if(GrainSize.MONTH.equals(grainSize)&&daysBetween<31){
            Assert.isTrue(false, "选择粒度月时，时间范围应大于1月");
        }
    }


    public static Date getTodayStartTime() {
        return getTodayStartTime(null);
    }


    public static Date getTodayEndTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    public static Date getTodayStartTime(Date nowMonthFirstDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowMonthFirstDay==null?new Date():nowMonthFirstDay);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 取某年的月份和每月的天数 输入的当前年份
     * @param year
     * @return
     */
    public static List<Map<String,Object>> monthAndEncapsulationNowYear(String year){
        // 获取当前日期
        LocalDate today = LocalDate.now();

        // 计算起始月份（去年当前月）
        YearMonth startMonth = YearMonth.from(today.minusYears(1));
        // 计算结束月份（今年当前月）
        YearMonth endMonth = YearMonth.from(today);

        // 生成年月字符串列表
        List<Map<String,Object>> yearMonths = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");

        // 从起始月份遍历到结束月份（含）
        for (YearMonth month = startMonth;
             !month.isAfter(endMonth);
             month = month.plusMonths(1)) {
            Map<String, Object> rem = new HashMap<>();
            rem.put("nianYue",month.format(formatter));
            yearMonths.add(rem);
        }
        return yearMonths;
    }
     /**
     * 获取某年的月份和每月的天数 输入的不是当前年份
     * @param nian
     * @return
     */
    public static List<Map<String,Object>> monthAndEncapsulationOldYear(String nian) {
        List<Map<String,Object>> data = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Calendar now = Calendar.getInstance();
        int a = now.get(Calendar.YEAR);
        Integer valueOf = Integer.valueOf(nian);
        if (a != valueOf) {
            for (int i = 1; i <= 12; i++) {
                Map<String, Object> yue = new HashMap<>();
                if (i <= 9 && i >= 1) {
                    String Date_str = nian + "-0" + i;
                    Date Date;
                    try {
                        Date = format.parse(Date_str);
                        yue.put("nianYue", Date_str);
                    } catch (ParseException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else {
                    String Date_str = nian + "-" + i;
                    Date Date;
                    try {
                        Date = format.parse(Date_str);
                        yue.put("nianYue", Date_str);

                    } catch (ParseException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                data.add(yue);
            }
        } else {
            Date date2 = new Date();
            int month = date2.getMonth() + 1;
            for (int i = 1; i <= month; i++) {
                Map<String, Object> yue = new HashMap<>();
                if (i <= 9 && i >= 1) {
                    String Date_str = nian + "-0" + i;
                    Date Date;
                    try {
                        Date = format.parse(Date_str);
                        yue.put("nianYue", Date_str);
                    } catch (ParseException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else {
                    String Date_str = nian + "-" + i;
                    Date Date;
                    try {
                        Date = format.parse(Date_str);
                        yue.put("nianYue", Date_str);

                    } catch (ParseException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                data.add(yue);
            }
        }
        return data;
    }
    // 获取每个月的天数
    public static int monthDays(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
    public static String upYearAndMonth(String nianyue){
        // 解析输入年月
        YearMonth yearMonth = YearMonth.parse(nianyue);
        // 获取上一个月
        YearMonth previousMonth = yearMonth.minusMonths(1);
        // 格式化为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        return previousMonth.format(formatter);
    }

    /**
     * 获取从昨天同一小时到当前小时的时间范围（精确到小时or分钟）
     *
     * @param inDate 输入日期
     * @return 时间字符串列表
     */
    public static List<String> getLast24HoursRange(String inDate) {
        List<String> hourList = new ArrayList<>();

        if (inDate.equals(getYYYYMMDDDate(new Date()))){
             //今天
            ZonedDateTime now = ZonedDateTime.now();
            ZonedDateTime yesterdaySameTime = now.minusHours(24);
            String pattern = "yyyy-MM-dd HH";
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
            ZonedDateTime current = yesterdaySameTime;
            while (!current.isAfter(now)) {
                hourList.add(current.format(formatter));
                current = current.plusHours(1);
            }
        }else{
            //非今天
            hourList = getAllHoursForDate(inDate);
        }
        return hourList;
    }

    /**
     * 获取指定日期所有小时时间点
     *
     * @param dateStr 日期字符串（格式：yyyy-MM-dd）
     * @return 24小时时间点列表（格式：yyyy-MM-dd HH）
     * @throws IllegalArgumentException 如果输入格式无效
     */
    public static List<String> getAllHoursForDate(String dateStr) {
        try {
            // 解析输入日期
            LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            // 创建结果列表
            List<String> hours = new ArrayList<>(24);
            // 生成00:00到23:00的时间点
            for (int i = 0; i < 24; i++) {
                LocalDateTime hourDateTime = date.atTime(i, 0);
                hours.add(hourDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH")));
            }
            return hours;
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("无效的日期格式: " + dateStr + "。请使用 yyyy-MM-dd 格式。");
        }
    }

    /**
     * 获取从上月今日到当月今日的日期范围
     *
     * @return 日期字符串列表（格式：yyyy-MM-dd）
     */
    public static List<String> getLastMonthToCurrentDates() {
        LocalDate startDate = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth())
                .minusDays(1); // 上个月的今日
        LocalDate endDate = LocalDate.now(); // 今天
        List<LocalDate> dateList = new ArrayList<>();
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            dateList.add(date);
        }
        List<String> collect = dateList.stream()
                .map(date -> date.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_DAY)))
                .collect(Collectors.toList());
        collect.remove(0);
        return collect;
    }

    /**
     * 获取指定日期对应的上月今日到当月今日的日期范围
     *
     * @param currentDate 当前日期
     * @return 日期字符串列表
     */
    public static List<String> getLastMonthToCurrentDates(LocalDate currentDate) {
        // 计算上月今日
        LocalDate lastMonthSameDay = calculateLastMonthSameDay(currentDate);

        // 生成日期范围
        return generateDateRange(lastMonthSameDay, currentDate);
    }

    /**
     * 计算上月今日（自动处理2月特殊情况）
     *
     * @param currentDate 当前日期
     * @return 上月对应的日期
     */
    private static LocalDate calculateLastMonthSameDay(LocalDate currentDate) {
        // 先减去一个月
        LocalDate lastMonth = currentDate.minusMonths(1);

        // 检查是否跨年
        if (lastMonth.getYear() < currentDate.getYear()) {
            return lastMonth;
        }

        // 获取当月的天数
        int daysInCurrentMonth = currentDate.lengthOfMonth();
        // 获取上个月的天数
        int daysInLastMonth = lastMonth.lengthOfMonth();

        // 如果上个月天数小于当前日期（如2月28日减去1个月变成1月28日，但3月31日减去1个月变成2月28/29日）
        if (currentDate.getDayOfMonth() > daysInLastMonth) {
            // 使用上个月的最后一天
            return lastMonth.with(TemporalAdjusters.lastDayOfMonth());
        }

        return lastMonth;
    }

    /**
     * 生成日期范围内的所有日期
     *
     * @param start 起始日期
     * @param end 结束日期
     * @return 日期列表
     */
    private static List<String> generateDateRange(LocalDate start, LocalDate end) {
        List<String> dates = new ArrayList<>();

        // 使用流API生成日期范围
        return Stream.iterate(start, date -> date.plusDays(1))
                .limit(Period.between(start, end).getDays() + 1)
                .map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
                .collect(Collectors.toList());
    }

    /**
     * 获取日期范围（带自定义格式）
     *
     * @param pattern 日期格式（如 "yyyy/MM/dd"）
     * @return 日期列表
     */
    public static List<String> getLastMonthToCurrentDates(String pattern) {
        LocalDate today = LocalDate.now();
        LocalDate lastMonthSameDay = calculateLastMonthSameDay(today);

        return Stream.iterate(lastMonthSameDay, date -> date.plusDays(1))
                .limit(Period.between(lastMonthSameDay, today).getDays() + 1)
                .map(date -> date.format(DateTimeFormatter.ofPattern(pattern)))
                .collect(Collectors.toList());
    }

    public static String getNowMonthAndDay(){
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        String currentYearMonth = currentDate.format(formatter);
        return currentYearMonth;
    }

    /**
     * 获取指定年月的所有日期对象
     *
     * @param yearMonth 年月字符串
     * @return LocalDate列表
     */
    public static List<String> getAllLocalDatesOfMonth(String yearMonth) {
        YearMonth targetMonth = YearMonth.parse(yearMonth, DateTimeFormatter.ofPattern("yyyy-MM"));

        List<LocalDate> locals = IntStream.rangeClosed(1, targetMonth.lengthOfMonth()).mapToObj(day -> LocalDate.of(targetMonth.getYear(), targetMonth.getMonth(), day))
                .collect(Collectors.toList());
        return locals.stream()
                .map(date -> date.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_DAY)))
                .collect(Collectors.toList());
    }

    public static List<String> getLast30Days() {
        List<String> dateList = new ArrayList<>();
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 计算30天前的日期
        LocalDate startDate = today.minusDays(30);

        // 日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 遍历日期范围（包含起止日期）
        for (LocalDate date = startDate; !date.isAfter(today); date = date.plusDays(1)) {
            dateList.add(date.format(formatter));
        }
        return dateList;
    }
    public static List<String> getLastByListDays(int days) {
        List<String> dateList = new ArrayList<>();
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 计算30天前的日期
        LocalDate startDate = today.minusDays(days);

        // 日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 遍历日期范围（包含起止日期）
        for (LocalDate date = startDate; !date.isAfter(today); date = date.plusDays(1)) {
            dateList.add(date.format(formatter));
        }
        return dateList;
    }
    public static String convertToHourFormat(String input) {
        // 定义输入格式解析器
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");

        // 解析字符串为 LocalDateTime 对象
        LocalDateTime dateTime = LocalDateTime.parse(input, inputFormatter);

        // 定义输出格式（HH 表示 24 小时制，自动补零）
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("HH:00");

        // 格式化为目标字符串
        return dateTime.format(outputFormatter);
    }


    /**
     * 获取当前日期指定多少天之前的日期
     * @return
     */
    public static String getLastDays(int days) {
        // 获取今天日期
        LocalDate today = LocalDate.now();
        // 计算30天前的日期
        LocalDate thirtyDaysAgo = today.minusDays(days);
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 格式化为字符串
        //String todayStr = today.format(formatter);
        String thirtyDaysAgoStr = thirtyDaysAgo.format(formatter);
        return thirtyDaysAgoStr;
    }
    /**
     * 时间比较方法
     * @param target
     * @param reference
     * @return
     */
    public static boolean compareTimes(LocalDateTime target, LocalDateTime reference) {
        if (target.isBefore(reference)) {
            //System.out.println("目标时间在当前时间之前");
            return true;
        } else if (target.isAfter(reference)) {
            //System.out.println("目标时间在当前时间之后");
            return false;
        } else {
            return false;
            //System.out.println("目标时间与当前时间相同");
        }
    }

    public static List<String> getHoursFrom1AM() {
        // 获取当前时间（精确到小时）
        LocalDateTime now = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);

        // 创建今日凌晨 1 点的时间
        LocalDateTime start = now.withHour(1);

        // 处理跨天情况（如果当前时间在凌晨 1 点前，则使用昨天的日期）
        if (now.isBefore(start)) {
            start = start.minusDays(1);
        }

        // 生成时间列表
        List<String> result = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");

        // 从凌晨 1 点开始逐小时增加到当前小时
        for (LocalDateTime time = start; !time.isAfter(now); time = time.plusHours(1)) {
            result.add(time.format(formatter));
        }

        return result;
    }
   public static String getLastDate(String yearMonth){
        // 解析年月
        YearMonth specifiedYearMonth = YearMonth.parse(yearMonth, DateTimeFormatter.ofPattern("yyyy-MM"));

        // 获取最后一天
        LocalDate lastDay = specifiedYearMonth.atEndOfMonth();

        // 格式化为 yyyy-MM-dd
        String lastDayFormatted = lastDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        return lastDayFormatted;
    }


}
